{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[toc] \n",
    "\n",
    "# HBMQTT\n",
    "\n",
    "本文介绍在python程序中如何接入异步 mqtt broker，异步客户端API和命令行用法请参考前面两篇文章。\n",
    "\n",
    "## 简介\n",
    "\n",
    "开源的Mqtt客户端和broker，使用python标准异步库`asyncio`实现，提供协程并发程序开发的直接API。\n",
    "\n",
    "- GitHub：https://github.com/beerfactory/hbmqtt\n",
    "- 文档：https://hbmqtt.readthedocs.io/en/latest/\n",
    "\n",
    "## Feature\n",
    "\n",
    "HBMQTT实现了完整的MQTT 3.1.1协议规范，并提供了以下特性：\n",
    "\n",
    "- Support QoS 0, QoS 1 and QoS 2 messages flow\n",
    "- 客户端断线自动重连\n",
    "- 通过密钥文件认证（其他方法可通过插件系统实现）\n",
    "- 基础的`$SYS` topics 支持\n",
    "- TCP 和 websocket 支持\n",
    "- TCP 和 websocket 的 SSL 支持\n",
    "- 插件系统\n",
    "\n",
    "## 依赖\n",
    "\n",
    "要求Python >=3.4.3\n",
    "\n",
    "## 安装\n",
    "\n",
    ">pip install hbmqtt==0.9.6\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Broker API参考\n",
    "\n",
    "`hbmqtt.broker.Broker`基于了MQTT 3.1.1 协议标准，实现了broker代理服务器的基本功能， \n",
    "\n",
    "## 1. 用法示例\n",
    "\n",
    "config 参数配置请参考前面文章 - 命令行基本用法 ，或者参考[官方示例](https://github.com/beerfactory/hbmqtt/blob/master/samples/)\n",
    "\n",
    "```py\n",
    "import asyncio\n",
    "import logging\n",
    "\n",
    "from hbmqtt.broker import Broker\n",
    "\n",
    "logger = logging.getLogger(__name__)\n",
    "\n",
    "config = {\n",
    "    'listeners': {\n",
    "        'default': {\n",
    "            'type': 'tcp',\n",
    "            'bind': '0.0.0.0:1883',\n",
    "            'max_connections': 10,\n",
    "        },\n",
    "    },\n",
    "    'sys_interval': 10,\n",
    "    'auth': {\n",
    "        'allow-anonymous': True,\n",
    "    },\n",
    "    'topic-check': {\n",
    "        'enabled': False\n",
    "    }\n",
    "}\n",
    "\n",
    "broker = Broker(config)\n",
    "\n",
    "\n",
    "async def test_coro():\n",
    "    # 启动\n",
    "    await broker.start()\n",
    "    await asyncio.sleep(5)\n",
    "    # 终止\n",
    "    await broker.shutdown()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    formatter = \"[%(asctime)s] :: %(levelname)s :: %(name)s :: %(message)s\"\n",
    "    logging.basicConfig(level=logging.INFO, format=formatter)\n",
    "    asyncio.get_event_loop().run_until_complete(test_coro())\n",
    "\n",
    "    # asyncio.get_event_loop().run_forever() # 让 broker 一直执行\n",
    "\n",
    "```\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. API 参考\n",
    "\n",
    "### 1. Broker构造方法 [[source]](https://hbmqtt.readthedocs.io/en/latest/_modules/hbmqtt/broker.html#Broker)\n",
    "\n",
    "```py\n",
    "class hbmqtt.broker.Broker(config=None, loop=None, plugin_namespace=None)\n",
    "```\n",
    "\n",
    "参数:\n",
    "\n",
    "- `config`: python字典类型，字段参考下文配置\n",
    "- `loop`： `asyncio`模块中的loop()对象\n",
    "- `plugin_namespace`：加载插件入口点时使用的插件命名空间，默认使用`hbmqtt.broker.plugins`\n",
    "\n",
    "### 2. broker.start\n",
    "\n",
    "协程，启动broker\n",
    "\n",
    "```py\n",
    "broker.start()\n",
    "```\n",
    "\n",
    "### 3. broker.shutdown\n",
    "\n",
    "协程， 关闭broker\n",
    "\n",
    "```py\n",
    "broker.shutdown()\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. python读取yaml\n",
    "\n",
    "读取从yaml文件，转为python对象\n",
    "\n",
    "```py\n",
    "import yaml\n",
    "\n",
    "with open('broker.yaml') as f:\n",
    "    print(yaml.safe_load(f))\n",
    "```\n",
    "\n",
    "## 3. 参数配置\n",
    "\n",
    "`Broker.__init__`构造方法需要一个config参数，类型为python字典。为了方便起见，下面以YAML文件的形式给出它\n",
    "\n",
    "```yaml\n",
    "listeners:\n",
    "    default:\n",
    "        max-connections: 50000\n",
    "        type: tcp\n",
    "    my-tcp-1:\n",
    "        bind: 127.0.0.1:1883\n",
    "    my-tcp-2:\n",
    "        bind: 1.2.3.4:1884\n",
    "        max-connections: 1000\n",
    "    my-tcp-ssl-1:\n",
    "        bind: 127.0.0.1:8885\n",
    "        ssl: on\n",
    "        cafile: /some/cafile\n",
    "        capath: /some/folder\n",
    "        capath: certificate data\n",
    "        certfile: /some/certfile\n",
    "        keyfile: /some/key\n",
    "    my-ws-1:\n",
    "        bind: 0.0.0.0:8080\n",
    "        type: ws\n",
    "timeout-disconnect-delay: 2\n",
    "auth:\n",
    "    plugins: ['auth.anonymous'] #List of plugins to activate for authentication among all registered plugins\n",
    "    allow-anonymous: true / false\n",
    "    password-file: /some/passwd_file\n",
    "```\n",
    "\n",
    "**listeners** : 可定义多个网络监听器，`default` 部分定义所有监听器的通用属性，每个监听器都有以下属性：\n",
    "\n",
    "- `bind`: IP 地址和端口号\n",
    "- `max`-connections: 最大监听客户端的数量，0代表无限制\n",
    "- `type`: 传输协议类型; 可以是 `tcp` 用于传统的TCP监听器，或者 `ws` 用于 websocket 传输 MQTT.\n",
    "- `ssl` enables (on) or disable secured connection over the transport protocol.\n",
    "- `cafile`, `cadata`, `certfile` and `keyfile` : SSL安全连接的必要参数。\n",
    "\n",
    "**auth**：设置身份验证行为\n",
    "\n",
    "- `plugins`: 声明激活的插件列表，这些插件必须定义在`hbmqtt.broker.plugins` 的[entry point](https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins)\n",
    "- `allow-anonymous`: 用于内部插件`hbmqtt.plugins.authentication.AnonymousAuthPlugin` ，决定是否允许匿名（无username）连接 broker。\n",
    "- `password-file`: 用于内部插件`hbmqtt.plugins.authentication.FileAuthPlugin`， 提供一个保存用户名+密码的文件路径\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "212.818px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
